package com.example.interview.reflect;

import java.lang.reflect.*;
import java.util.Date;

//java反射之遍历类中所有内部类及属性方法 https://blog.csdn.net/weixin_33826268/article/details/93088757
public class TestMain {

    public static void main(String[] args) {
//        test();
        test2();
    }

    //1.操作-枚举
    public static void test() {
        //根据反射获取常量类
        try {
            Class c2 = Class.forName("com.example.interview.reflect.BeanTest");
            //获取常量类中的所有内部类
            Class innerClazz[] = c2.getDeclaredClasses();
            //遍历内部内
            for (Class class1 : innerClazz) {
                //判断类是不是枚举类
                if (class1.isEnum()) {
                    //获取内部内的类名，在这里其实就是获取枚举类
                    String simpleName = class1.getSimpleName();
                    //反射获取枚举类
                    Class<Enum> clazz = (Class<Enum>) Class.forName("com.example.interview.reflect.BeanTest$" + simpleName);
                    //获取所有枚举实例
                    Enum[] enumConstants = clazz.getEnumConstants();
                    //根据方法名获取方法
                    Method getCode = clazz.getMethod("getDesc");
                    for (Enum enum1 : enumConstants) {
                        //得到枚举实例名
                        String name2 = enum1.name();
                        //执行枚举方法获得枚举实例对应的值
                        Object invoke = getCode.invoke(enum1);
                        System.out.println(name2 + ":" + invoke.toString());
                    }
                }

            }

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static String getMethodName(String fildeName) {
        byte[] items = fildeName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }

    //2.操作-内部类
    public static void test2() {

        try {
            Class classBuild = Class.forName("com.example.interview.reflect.BeanTest");

//-------------------------------------2019 - 6 - 10 haidragon修改   ------------------------------------
            //遍历内部类
//            for (final Class class1 : classBuild.getDeclaredClasses()){
//                //判断类是不是枚举类
//                if(class1.isEnum()){
//                    //获取内部内的类名，在这里其实就是获取枚举类
//                    String simpleName = class1.getSimpleName();
//                    System.out.println("枚举类名："+simpleName);
//                    //反射获取枚举类
//                    Class<Enum> clazz = (Class<Enum>)Class.forName("com.example.interview.reflect.BeanTest$"+simpleName);
//                    //获取所有枚举实例
//                    Enum[] enumConstants = clazz.getEnumConstants();
//                    //根据方法名获取方法
//                    Method getCode = clazz.getMethod("getDesc");
//                    for (Enum enum1 : enumConstants) {
//                        //得到枚举实例名
//                        String name2 = enum1.name();
//                        //执行枚举方法获得枚举实例对应的值
//                        Object invoke = getCode.invoke(enum1);
//                        System.out.println(name2+":"+invoke.toString());
//                        System.out.println("获得枚举实例对应的值："+name2+":"+invoke.toString());
//                    }
//                    //其它类
//                }else {
//                    System.out.println("内部内的类名："+class1.getSimpleName());
//                    for (final  Method method:class1.getDeclaredMethods()){
//                        System.out.println("内部内的类中的方法名："+method.getName());
//                    }
//                }
//            }

//            //遍历所有构造函数
//            for (final Constructor<?> constructor : classBuild.getConstructors()) {
//                System.out.println("构造函数："+constructor.getName());
//            }

            //遍历所有的方法
            // getDeclaredMethods() 该方法是获取本类中的所有方法，包括私有的(private、protected、默认以及public)的方法。
            for (final Method one : classBuild.getMethods()) {
//                System.out.print(one.getName() + "--" + one.getParameterCount() + "(");
                Class[] paramTypes = one.getParameterTypes();
                Parameter[] parameters = one.getParameters();
                StringBuilder sb = new StringBuilder();
                sb.append(one.getName()+"");
                sb.append("(");
                for (int i = 0; i < one.getParameterCount(); i++) {
                    sb.append(paramTypes[i].getName() + " " + parameters[i].getName() + ",");
                }
                sb.append(")");
                String sbs = sb.toString();
                int su = sbs.lastIndexOf(",");
                sbs = su > 0 ? sbs.substring(0, su) + sbs.substring(su+1, sbs.length()) : sbs;
                System.out.println(sbs);

//                Class superClass = BeanTest.class.getSuperclass();
//                System.out.println(superClass.getName());

            }



//            //遍历所有属性
//            for (final Field field : classBuild.getFields()){ //getDeclaredFields
//                System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers());
//            }
//
//            //遍历所有属性(属性名，类型，修饰符)
//            for (final Field field : classBuild.getDeclaredFields()) { // --for() begin
//                System.out.println("类中的属性名："+field.getName() +"；类型："+field.getGenericType().toString() +"；类型修改符 ："+field.getModifiers());
//                // 如果类型是String
//                if (field.getGenericType().toString().equals("class java.lang.String")) { // 如果type是类类型，则前面包含"class "，后面跟类名
//                    // 拿到该属性的gettet方法
//                    /**
//                     * 这里需要说明一下：他是根据拼凑的字符来找你写的getter方法的
//                     * 在Boolean值的时候是isXXX（默认使用ide生成getter的都是isXXX）
//                     * 如果出现NoSuchMethod异常 就说明它找不到那个gettet方法 需要做个规范
//                     */
//                    Method m = (Method) classBuild.getMethod("get" + getMethodName(field.getName()));
//
//                    String val = (String) m.invoke(new BeanTest());// 调用getter方法获取属性值
//                    if (val != null) {
//                        System.out.println("String type:" + val);
//                        System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers()+" val:"+val);
//                    }
//                }
//
//                // 如果类型是Integer
//                if (field.getGenericType().toString().equals(
//                        "class java.lang.Integer")) {
//                    Method m = (Method) classBuild.getClass().getMethod("get" + getMethodName(field.getName()));
//                    Integer val = (Integer) m.invoke(classBuild);
//                    if (val != null) {
//                        System.out.println("Integer type:" + val);
//                        System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers()+" val:"+val);
//                    }
//                }
//
//                // 如果类型是Double
//                if (field.getGenericType().toString().equals(
//                        "class java.lang.Double")) {
//                    Method m = (Method) classBuild.getClass().getMethod("get" + getMethodName(field.getName()));
//                    Double val = (Double) m.invoke(classBuild);
//                    if (val != null) {
//                        System.out.println("Double type:" + val);
//                        System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers()+" val:"+val);
//                    }
//                }
//
//                // 如果类型是Boolean 是封装类
//                if (field.getGenericType().toString().equals(
//                        "class java.lang.Boolean")) {
//                    Method m = (Method) classBuild.getClass().getMethod(field.getName());
//                    Boolean val = (Boolean) m.invoke(classBuild);
//                    if (val != null) {
//                        System.out.println("Boolean type:" + val);
//                        System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers()+" val:"+val);
//                    }
//                }
//
//                // 如果类型是boolean 基本数据类型不一样 这里有点说名如果定义名是 isXXX的 那就全都是isXXX的
//                // 反射找不到getter的具体名
//                if (field.getGenericType().toString().equals("boolean")) {
//                    Method m = (Method) classBuild.getClass().getMethod(field.getName());
//                    Boolean val = (Boolean) m.invoke(classBuild);
//                    if (val != null) {
//                        System.out.println("boolean type:" + val);
//                        System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers()+" val:"+val);
//                    }
//                }
//                // 如果类型是Date
//                if (field.getGenericType().toString().equals(
//                        "class java.util.Date")) {
//                    Method m = (Method) classBuild.getClass().getMethod("get" + getMethodName(field.getName()));
//                    Date val = (Date) m.invoke(classBuild);
//                    if (val != null) {
//                        System.out.println("Date type:" + val);
//                        System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers()+" val:"+val);
//                    }
//                }
//                // 如果类型是Short
//                if (field.getGenericType().toString().equals(
//                        "class java.lang.Short")) {
//                    Method m = (Method) classBuild.getClass().getMethod("get" + getMethodName(field.getName()));
//                    Short val = (Short) m.invoke(classBuild);
//                    if (val != null) {
//                        System.out.println("Short type:" + val);
//                        System.out.println("类中的属性名："+field.getName()+"类型："+field.getGenericType().toString() +"类型修改符 ："+field.getModifiers()+" val:"+val);
//                    }
//                }
//                // 其他的类型
//
//            }//for() --end


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
//        catch (NoSuchMethodException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        } catch (InvocationTargetException e) {
//            e.printStackTrace();
//        }

    }

}
